package com.aiou.security.authentication.wechat;

import com.aiou.common.utils.JacksonUtils;
import com.aiou.security.validate.code.ValidateCodeException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Map;

/**
 * @author: zyb
 * @date: 2018-09-10 14:59
 */
@Slf4j
public abstract class AbstractWeChatUserDetailsService implements WeChatUserDetailsService {
    private RestTemplate restTemplate = new RestTemplate();
    private static final String SESSION_KEY_URL = "https://api.weixin.qq.com/sns/jscode2session";

    @Override
    @SuppressWarnings("unchecked")
    public WeChatUserDetails loadUserByCode(String code, String appId, String appSecret) {
        UriComponents components = UriComponentsBuilder.fromHttpUrl(SESSION_KEY_URL)
                .queryParam("appid", appId)
                .queryParam("secret", appSecret)
                .queryParam("js_code", code)
                .queryParam("grant_type", "authorization_code")
                .build();
        String responseStr = restTemplate.getForObject(components.toUriString(), String.class);
        log.info("send wechat response: {}.", responseStr);
        if (responseStr != null && !responseStr.contains("session_key")) {
            throw new ValidateCodeException("授权无效！请重新授权");
        }
        Map map = JacksonUtils.parse(responseStr, Map.class);
        String openId = MapUtils.getString(map, "openid");
        String sessionKey = MapUtils.getString(map, "session_key");
        String unionid = MapUtils.getString(map, "unionid");
        WeChatUserDetails weChatUserDetails = loadUserByOpenIdOrUnionId(openId, unionid, sessionKey);
        weChatUserDetails.setOpenId(openId);
        weChatUserDetails.setSessionKey(sessionKey);
        weChatUserDetails.setUnionid(unionid);
        return weChatUserDetails;
    }

    /**
     * 根据openid 或者 unionid 查询用户
     *
     * @param openId
     * @param unionid
     * @param sessionKey
     * @return
     */
    public abstract WeChatUserDetails loadUserByOpenIdOrUnionId(String openId, String unionid, String sessionKey);
}
